<script setup lang="ts">
import { ref, computed, watch, onMounted, nextTick } from 'vue'
import { i18n } from 'boot/i18n'
import api from 'src/api'
import { Notify, QSpinnerBall } from 'quasar'
import type { RoomType } from 'src/api/service'
import dayjs from 'dayjs'
import { useRouter } from 'vue-router'
import { useLocalStorage } from '@vueuse/core'

const router = useRouter()
const tc = i18n.global.tc

interface MeetingInfo {
  meeting_id: string;
  meeting_code: string;
  subject: string;
  userid: string;
  nick_name: string;
  start_time: number;
  end_time: number;
  online_member_num: number;
  meeting_state: number;
  meeting_type: number;
}

// 会议类型映射
const MEETING_TYPES: Record<number, string> = {
  0: '一次性会议',
  1: '周期性会议',
  2: '微信专属会议',
  4: 'Rooms投屏会议',
  5: '个人会议号会议',
  6: '网络研讨会'
}

// 会议状态映射
const MEETING_STATES: Record<number, string> = {
  1: '待开始',
  2: '进行中',
  3: '已结束'
}

// 获取会议状态
const getMeetingState = (startTime: number, endTime: number): number => {
  const now = Math.floor(Date.now() / 1000) // 当前时间戳（秒）
  if (now < startTime) {
    return 1 // 待开始
  } else if (now >= startTime && now <= endTime) {
    return 2 // 进行中
  } else {
    return 3 // 已结束
  }
}

// 格式化会议类型
const formatMeetingType = (type: number) => {
  return MEETING_TYPES[type] || tc('未知类型')
}

// 格式化会议状态
const formatMeetingState = (startTime: number, endTime: number) => {
  const state = getMeetingState(startTime, endTime)
  return MEETING_STATES[state] || tc('未知状态')
}

// 获取状态颜色
const getStateColor = (startTime: number, endTime: number) => {
  const state = getMeetingState(startTime, endTime)
  switch (state) {
    case 1:
      return 'accent' // 待开始
    case 2:
      return 'positive' // 进行中
    case 3:
      return 'grey' // 已结束
    default:
      return 'grey'
  }
}

// 表单数据
const meetingForm = ref({
  meetingId: '',
  topic: '',
  startTime: '',
  endTime: ''
})

// 时间选择器数据
const reserveTimeModel = ref({
  startDate: '',
  startTime: '',
  endDate: '',
  endTime: ''
})

// 当前选中的周期会议索引
const selectedPeriodicMeetingIndex = ref(-1)

const loadingMeetingInfo = ref(false)
const meetingInfo = ref<MeetingInfo | null>(null)
const periodicMeetings = ref<MeetingInfo[]>([])
const formValid = ref(false)

// 时间校验状态
const timeErrors = ref({
  startTimeInPast: false,
  endTimeBeforeStart: false,
  durationTooShort: false,
  durationTooLong: false,
  invalidDateTimeFormat: false
})

// 表单验证状态
const timeValid = computed(() => {
  if (meetingForm.value.startTime && meetingForm.value.endTime) {
    // 先检查是否能正确转换为Date对象
    const start = new Date(meetingForm.value.startTime)
    const end = new Date(meetingForm.value.endTime)

    // 检查日期是否有效
    if (isNaN(start.getTime()) || isNaN(end.getTime())) {
      return false
    }

    const now = new Date()
    const durationMs = end.getTime() - start.getTime()
    const durationMinutes = durationMs / (1000 * 60)

    // 只检查条件而不更新状态
    return !(
      start < now ||
      end <= start ||
      (end > start && durationMinutes < 15) ||
      (end > start && durationMinutes > 24 * 60)
    )
  }
  return false
})

// 监听开始和结束时间变化，更新错误状态
watch(
  [() => meetingForm.value.startTime, () => meetingForm.value.endTime],
  () => {
    // 首先重置所有错误状态
    timeErrors.value = {
      startTimeInPast: false,
      endTimeBeforeStart: false,
      durationTooShort: false,
      durationTooLong: false,
      invalidDateTimeFormat: false
    }

    const { startTime, endTime } = meetingForm.value

    if (startTime && endTime) {
      const start = new Date(startTime)
      const end = new Date(endTime)

      if (isNaN(start.getTime()) || isNaN(end.getTime())) {
        timeErrors.value.invalidDateTimeFormat = true
        return // 如果日期格式无效，则不进行后续检查
      }

      const now = new Date()
      const durationMs = end.getTime() - start.getTime()
      const durationMinutes = durationMs / (1000 * 60)

      timeErrors.value.startTimeInPast = start < now
      timeErrors.value.endTimeBeforeStart = end <= start
      // 只有当结束时间确实晚于开始时间时，才检查时长
      if (end > start) {
        timeErrors.value.durationTooShort = durationMinutes < 15
        timeErrors.value.durationTooLong = durationMinutes > (24 * 60)
      }
    } else if (startTime || endTime) {
      // 如果只有一个时间被设置，也认为是格式不完整/无效
      timeErrors.value.invalidDateTimeFormat = true
    }
    // 如果 startTime 和 endTime 都为空，所有错误都应为 false (已在重置时完成)
  },
  { immediate: true }
)

// 计算当前会议时长（小时和分钟），超过24小时也显示为小时，不换算为天
const currentDuration = computed(() => {
  if (meetingForm.value.startTime && meetingForm.value.endTime) {
    const start = new Date(meetingForm.value.startTime)
    const end = new Date(meetingForm.value.endTime)

    if (start >= end) return { hours: 0, minutes: 0 }

    const durationMs = end.getTime() - start.getTime()
    const totalMinutes = Math.floor(durationMs / (1000 * 60))

    // 即使超过24小时，仍然以小时显示，不转换为天
    const hours = Math.floor(totalMinutes / 60)
    const minutes = totalMinutes % 60

    return { hours, minutes }
  }
  return { hours: 0, minutes: 0 }
})

// 定义单个房间的类型接口
interface RoomInfo {
  type: RoomType;
  name: string;
  available: number;
  selected: boolean;
}

// 可用会议室 (使用接口进行类型注解)
const availableRooms = ref<RoomInfo[]>([
  { type: 50, name: '50方会议室', available: 0, selected: false },
  { type: 100, name: '100方会议室', available: 0, selected: false },
  { type: 300, name: '300方会议室', available: 0, selected: false },
  { type: 500, name: '500方会议室', available: 0, selected: false },
  { type: 1000, name: '1000方会议室', available: 0, selected: false }
])

// 会议室配置接口
interface RoomConfig {
  type_50_visible: boolean;
  type_100_visible: boolean;
  type_300_visible: boolean;
  type_500_visible: boolean;
  type_1000_visible: boolean;
}

// 会议室配置（用于确定可见性）
const roomConfig = ref<RoomConfig | null>(null)

// 获取会议室配置
const fetchRoomConfig = async () => {
  try {
    const response = await api.service.txMeeting.getMeetingRoomConfig()
    if (response.data && response.data.room_info) {
      roomConfig.value = response.data.room_info

      // 根据可见性设置过滤可用会议室列表
      const allRoomTypes = [
        { type: 50, name: '50方会议室', visible: roomConfig.value.type_50_visible },
        { type: 100, name: '100方会议室', visible: roomConfig.value.type_100_visible },
        { type: 300, name: '300方会议室', visible: roomConfig.value.type_300_visible },
        { type: 500, name: '500方会议室', visible: roomConfig.value.type_500_visible },
        { type: 1000, name: '1000方会议室', visible: roomConfig.value.type_1000_visible }
      ]

      // 只显示可见的会议室类型
      availableRooms.value = allRoomTypes
        .filter(room => room.visible)
        .map(room => ({
          type: room.type as RoomType,
          name: room.name,
          available: 0,
          selected: false
        }))
    }
  } catch (error) {
    console.error('Error fetching room config:', error)
    // 如果获取配置失败，保留所有会议室类型
  }
}

// 加载状态
const loadingAvailableRooms = ref(false)
const submittingBooking = ref(false)

// 会议预定须知
const termsConditions = ref('')
const loadingTerms = ref(false)
// 使用 useLocalStorage 来保存展开/折叠状态，默认为 true (展开)
const termsExpanded = useLocalStorage('meeting-terms-expanded', true)

// 格式化日期时间
const formatDateTime = (timestamp: number) => {
  return dayjs(timestamp * 1000).format('YYYY-MM-DD HH:mm:ss')
}

// 格式化日期时间模型到标准ISO格式
const formatDateTimeModel = (date: string, time: string): string => {
  if (!date || !time) return ''
  return `${date}T${time}`
}

// 将时间取整到15分钟
const roundTimeToQuarter = (date: Date, roundUp = false): Date => {
  const minutes = date.getMinutes()
  const remainder = minutes % 15

  if (remainder === 0) return date // 已经是15分钟的整数倍

  const roundedDate = new Date(date)
  if (roundUp) {
    // 向上取整
    roundedDate.setMinutes(minutes + (15 - remainder))
  } else {
    // 向下取整
    roundedDate.setMinutes(minutes - remainder)
  }

  return roundedDate
}

// 创建时间选项数组
const timeOptions = computed(() => {
  const options = []

  // 添加00:00到23:45的选项
  for (let hour = 0; hour < 24; hour++) {
    for (let minute = 0; minute < 60; minute += 15) {
      options.push({
        value: `${hour.toString().padStart(2, '0')}:${minute.toString().padStart(2, '0')}`,
        label: `${hour.toString().padStart(2, '0')}:${minute.toString().padStart(2, '0')}`
      })
    }
  }

  // 添加24:00选项
  options.push({
    value: '24:00',
    label: '24:00'
  })

  return options
})

// 监听开始时间变化 (只有时间可以修改)
watch(
  [() => reserveTimeModel.value.startTime],
  () => {
    // 不再进行自动调整
  }
)

// 监听结束时间变化 (只有时间可以修改)
watch(
  [() => reserveTimeModel.value.endTime],
  () => {
    // 不再进行自动调整
  }
)

// 监听时间选择器变化并更新主表单
watch(
  [
    () => reserveTimeModel.value.startDate,
    () => reserveTimeModel.value.startTime,
    () => reserveTimeModel.value.endDate,
    () => reserveTimeModel.value.endTime
  ],
  () => {
    const { startDate, startTime, endDate, endTime } = reserveTimeModel.value

    if (startDate && startTime) {
      meetingForm.value.startTime = formatDateTimeModel(startDate, startTime)
    }

    if (endDate && endTime) {
      meetingForm.value.endTime = formatDateTimeModel(endDate, endTime)
    } else {
      // 确保清空结束时间，避免无效值
      meetingForm.value.endTime = ''
    }
  }
)

// 自动获取可用会议室当时间有效时
watch(
  [() => meetingForm.value.startTime, () => meetingForm.value.endTime],
  () => {
    // 只有当时间有效时自动获取
    if (timeValid.value) {
      fetchAvailableRooms()
    } else {
      // 时间无效，重置可用数量
      availableRooms.value.forEach((room) => {
        room.available = 0
        room.selected = false
      })
      checkFormValid()
    }
  }
)

// 从会议信息加载时间到时间选择器
const loadMeetingTimesToPicker = () => {
  if (meetingInfo.value) {
    try {
      // 获取当前时间戳（秒）
      const now = Math.floor(Date.now() / 1000)

      // 确定开始时间
      let startTimestamp = meetingInfo.value.start_time

      // 如果会议已经开始，则将开始时间调整为当前时间后的最近15分钟整点
      if (now > startTimestamp) {
        // 将当前时间转换为Date对象
        const currentDate = new Date()
        // 向上取整到最近的15分钟
        const roundedDate = roundTimeToQuarter(currentDate, true)
        // 转换回时间戳（秒）
        startTimestamp = Math.floor(roundedDate.getTime() / 1000)
      }

      // 开始时间向下取整到15分钟
      const startDate = new Date(startTimestamp * 1000)
      const roundedStartDate = roundTimeToQuarter(startDate)

      // 结束时间向上取整到15分钟
      const endDate = new Date(meetingInfo.value.end_time * 1000)
      const roundedEndDate = roundTimeToQuarter(endDate, true)

      // 检查时间是否有效
      if (isNaN(roundedStartDate.getTime()) || isNaN(roundedEndDate.getTime())) {
        console.error('会议时间转换失败', startDate, endDate)
        return
      }

      // 更新时间选择器模型
      reserveTimeModel.value.startDate =
        dayjs(roundedStartDate).format('YYYY-MM-DD')
      reserveTimeModel.value.startTime = dayjs(roundedStartDate).format('HH:mm')
      reserveTimeModel.value.endDate = dayjs(roundedEndDate).format('YYYY-MM-DD')
      reserveTimeModel.value.endTime = dayjs(roundedEndDate).format('HH:mm')

      // 更新主表单
      meetingForm.value.startTime = formatDateTimeModel(
        reserveTimeModel.value.startDate,
        reserveTimeModel.value.startTime
      )
      meetingForm.value.endTime = formatDateTimeModel(
        reserveTimeModel.value.endDate,
        reserveTimeModel.value.endTime
      )

      // 如果是周期会议，默认选中第一个时间段
      if (meetingInfo.value.meeting_type === 1 && periodicMeetings.value.length > 0) {
        // 默认选中第一个时间段
        selectedPeriodicMeetingIndex.value = 0
      }
    } catch (error) {
      console.error('加载会议时间失败', error)
      Notify.create({
        message: tc('加载会议时间失败'),
        type: 'negative',
        position: 'top'
      })
    }
  }
}

// 选择会议室
const selectRoom = (index: number) => {
  // 重置所有选择
  availableRooms.value.forEach((room, i) => {
    // 只要有可用会议室就可以被选中
    room.selected = i === index && room.available > 0
  })
  checkFormValid()
}

// 检查表单是否有效
const checkFormValid = () => {
  const form = meetingForm.value

  // 检查是否有房间被选中
  const roomSelected = availableRooms.value.some((room) => room.selected)

  // 表单有效性
  formValid.value =
    timeValid.value &&
    !!form.meetingId &&
    !!form.topic &&
    roomSelected
}

// 确认预订
const confirmBooking = async () => {
  if (!formValid.value) return

  const selectedRoom = availableRooms.value.find((room) => room.selected)
  if (!selectedRoom) {
    Notify.create({
      message: tc('请选择一个会议室'),
      type: 'warning',
      icon: 'warning',
      position: 'top'
    })
    return
  }

  submittingBooking.value = true
  // 保存 dismiss 函数
  const dismissSubmit = Notify.create({
    message: tc('正在提交预定...'),
    type: 'ongoing',
    spinner: QSpinnerBall,
    position: 'center',
    timeout: 0
  })

  try {
    const payload = {
      subject: meetingForm.value.topic,
      meeting_code: meetingInfo.value ? meetingInfo.value.meeting_code : meetingForm.value.meetingId,
      start_time: Math.floor(
        new Date(meetingForm.value.startTime).getTime() / 1000
      ),
      end_time: Math.floor(
        new Date(meetingForm.value.endTime).getTime() / 1000
      ),
      people_num: 3, // 默认使用固定值
      room_type: selectedRoom.type // 类型现在匹配了
    }
    const response = await api.service.txMeeting.createReservation(payload)
    dismissSubmit() // 关闭进行中通知

    if (response.data && response.data.id) {
      Notify.create({
        message: tc('会议预定成功'),
        type: 'positive',
        icon: 'check',
        position: 'top'
      })
      resetForm()

      // 预定成功后跳转到我的预定页面的日历视图
      router.push({
        path: '/my/meeting/my-bookings'
      })
    } else {
      Notify.create({
        message: tc('会议预定失败，未返回预定信息'),
        type: 'negative',
        icon: 'error',
        position: 'top'
      })
    }
  } catch (error: unknown) {
    dismissSubmit() // 确保在 catch 中也关闭
    console.error('Error creating reservation:', error)
    // 使用类型断言处理错误对象
    interface ErrorWithResponse {
      response?: {
        data?: {
          detail?: string;
          code?: string;
          message?: string;
        };
      };
    }
    const errorWithResponse = error as ErrorWithResponse
    // 优先使用详细错误信息 (code+message) 或 detail
    const errorMessage =
      (errorWithResponse?.response?.data?.code && errorWithResponse?.response?.data?.message
        ? `${errorWithResponse.response.data.code}: ${errorWithResponse.response.data.message}`
        : errorWithResponse?.response?.data?.detail) ||
      tc('会议预定失败，请稍后重试')
    Notify.create({
      message: errorMessage,
      type: 'negative',
      icon: 'error',
      position: 'top'
    })
  } finally {
    submittingBooking.value = false
  }
}

// 重置表单
const resetForm = () => {
  meetingForm.value = {
    meetingId: '',
    topic: '',
    startTime: '',
    endTime: ''
  }
  // 重置时间选择器
  reserveTimeModel.value = {
    startDate: '',
    startTime: '',
    endDate: '',
    endTime: ''
  }
  // 重置选中的周期会议索引
  selectedPeriodicMeetingIndex.value = -1
  availableRooms.value.forEach((room) => {
    room.selected = false
    room.available = 0 // 重置可用数量
  })
  formValid.value = false
  // 不需要重置 timeError，因为它依赖于 timeValid
}

// 获取预定须知
const fetchTermsConditions = async () => {
  loadingTerms.value = true
  try {
    const response = await api.service.txMeeting.getTermsConditions()
    termsConditions.value = response.data.content
  } catch (error) {
    console.error('Error fetching terms and conditions:', error)
    // Optionally show a notification
  } finally {
    loadingTerms.value = false
  }
}

// 组件挂载时获取须知
onMounted(() => {
  fetchTermsConditions()
  fetchRoomConfig() // 获取会议室配置以确定可见性

  // 确保在加载前设置loadingAvailability为true
  loadingAvailability.value = true
  // 加载可用性数据
  fetchRoomAvailabilityData()
})

// 重置时间为原始会议时间
const resetToMeetingTime = () => {
  if (!meetingInfo.value) return

  try {
    // 确保清空当前的时间，避免潜在的无效状态
    reserveTimeModel.value = {
      startDate: '',
      startTime: '',
      endDate: '',
      endTime: ''
    }

    // 根据会议类型处理
    if (meetingInfo.value.meeting_type === 1 && periodicMeetings.value.length > 0) {
      // 周期性会议：根据当前选中的周期会议选项重置时间
      if (selectedPeriodicMeetingIndex.value >= 0 &&
        selectedPeriodicMeetingIndex.value < periodicMeetings.value.length) {
        // 获取当前选中的周期会议
        const selectedMeeting = periodicMeetings.value[selectedPeriodicMeetingIndex.value]

        // 获取当前时间戳（秒）
        const now = Math.floor(Date.now() / 1000)

        // 确定开始时间
        let startTimestamp = selectedMeeting.start_time

        // 如果会议已经开始，则将开始时间调整为当前时间后的最近15分钟整点
        if (now > startTimestamp) {
          // 将当前时间转换为Date对象
          const currentDate = new Date()
          // 向上取整到最近的15分钟
          const roundedDate = roundTimeToQuarter(currentDate, true)
          // 转换回时间戳（秒）
          startTimestamp = Math.floor(roundedDate.getTime() / 1000)
        }

        // 开始时间和结束时间取整
        const startDate = new Date(startTimestamp * 1000)
        const roundedStartDate = roundTimeToQuarter(startDate)

        const endDate = new Date(selectedMeeting.end_time * 1000)
        const roundedEndDate = roundTimeToQuarter(endDate, true)

        // 更新时间选择器模型
        reserveTimeModel.value.startDate = dayjs(roundedStartDate).format('YYYY-MM-DD')
        reserveTimeModel.value.startTime = dayjs(roundedStartDate).format('HH:mm')
        reserveTimeModel.value.endDate = dayjs(roundedEndDate).format('YYYY-MM-DD')
        reserveTimeModel.value.endTime = dayjs(roundedEndDate).format('HH:mm')
      } else {
        // 如果没有选中任何选项，默认选择第一个
        selectedPeriodicMeetingIndex.value = 0
        resetToMeetingTime() // 递归调用自身
        return
      }
    } else {
      // 一次性会议：使用会议的原始时间
      // 开始时间向下取整到15分钟
      const startDate = new Date(meetingInfo.value.start_time * 1000)
      const roundedStartDate = roundTimeToQuarter(startDate)

      // 结束时间向上取整到15分钟
      const endDate = new Date(meetingInfo.value.end_time * 1000)
      const roundedEndDate = roundTimeToQuarter(endDate, true)

      // 更新时间选择器模型
      reserveTimeModel.value.startDate = dayjs(roundedStartDate).format('YYYY-MM-DD')
      reserveTimeModel.value.startTime = dayjs(roundedStartDate).format('HH:mm')
      reserveTimeModel.value.endDate = dayjs(roundedEndDate).format('YYYY-MM-DD')
      reserveTimeModel.value.endTime = dayjs(roundedEndDate).format('HH:mm')
    }

    // 更新主表单
    meetingForm.value.startTime = formatDateTimeModel(
      reserveTimeModel.value.startDate,
      reserveTimeModel.value.startTime
    )
    meetingForm.value.endTime = formatDateTimeModel(
      reserveTimeModel.value.endDate,
      reserveTimeModel.value.endTime
    )

    // 显示提示
    Notify.create({
      message: tc('已重置为原始会议时间'),
      type: 'info',
      position: 'top'
    })
  } catch (error) {
    console.error('重置会议时间失败', error)
    Notify.create({
      message: tc('重置会议时间失败'),
      type: 'negative',
      position: 'top'
    })
  }
}

// 获取会议信息
const fetchMeetingInfo = async () => {
  if (!meetingForm.value.meetingId) return

  loadingMeetingInfo.value = true
  periodicMeetings.value = [] // 重置周期会议列表
  selectedPeriodicMeetingIndex.value = -1 // 重置选中的周期会议索引

  try {
    // 只保留会议号中的数字，去除所有其他字符
    const cleanMeetingId = meetingForm.value.meetingId.replace(/\D/g, '')
    const response = await api.service.txMeeting.getTencentMeetingInfo({
      meeting_code: cleanMeetingId
    })

    if (response.data.meeting_info_list.length > 0) {
      // 获取第一个会议信息作为主信息
      const info = response.data.meeting_info_list[0]
      meetingInfo.value = {
        meeting_id: info.meeting_id,
        meeting_code: info.meeting_code,
        subject: info.subject,
        userid: info.userid,
        nick_name: info.nick_name,
        start_time: info.start_time,
        end_time: info.end_time,
        online_member_num: info.online_member_num,
        meeting_state: getMeetingState(info.start_time, info.end_time),
        meeting_type: info.meeting_type
      }

      meetingForm.value.topic = info.subject

      // 如果是周期性会议，保存所有时间段
      if (
        info.meeting_type === 1 &&
        response.data.meeting_info_list.length > 1
      ) {
        periodicMeetings.value = response.data.meeting_info_list.map(
          (meeting) => ({
            meeting_id: meeting.meeting_id,
            meeting_code: meeting.meeting_code,
            subject: meeting.subject,
            userid: meeting.userid,
            nick_name: meeting.nick_name,
            start_time: meeting.start_time,
            end_time: meeting.end_time,
            online_member_num: meeting.online_member_num,
            meeting_state: getMeetingState(
              meeting.start_time,
              meeting.end_time
            ),
            meeting_type: meeting.meeting_type
          })
        )
      }

      // 加载会议时间到时间选择器（这会自动选择匹配的周期会议）
      loadMeetingTimesToPicker()

      Notify.create({
        message: tc('会议信息已加载'),
        type: 'positive',
        icon: 'check',
        position: 'top'
      })
      checkFormValid()
    } else {
      Notify.create({
        message: tc('未找到对应的腾讯会议信息'),
        type: 'warning',
        icon: 'warning',
        position: 'top'
      })
      meetingInfo.value = null
    }
  } catch (error) {
    console.error('获取会议信息失败:', error)
    Notify.create({
      message: tc('获取会议信息失败'),
      type: 'negative',
      icon: 'error',
      position: 'top'
    })
    meetingInfo.value = null
  } finally {
    loadingMeetingInfo.value = false
  }
}

// 获取可用会议室
const fetchAvailableRooms = async () => {
  if (!timeValid.value) return

  // 额外检查开始和结束时间是否为有效值
  if (!meetingForm.value.startTime || !meetingForm.value.endTime) {
    console.error('无效的时间格式', meetingForm.value.startTime, meetingForm.value.endTime)
    return
  }

  const startTime = new Date(meetingForm.value.startTime).getTime()
  const endTime = new Date(meetingForm.value.endTime).getTime()

  // 确保两个时间都是有效数字
  if (isNaN(startTime) || isNaN(endTime)) {
    console.error('时间转换为时间戳失败', startTime, endTime)
    return
  }

  loadingAvailableRooms.value = true
  // 重置可用数量和选择状态
  availableRooms.value.forEach((room) => {
    room.available = 0
    room.selected = false
  })

  try {
    const startTimestamp = Math.floor(startTime / 1000)
    const endTimestamp = Math.floor(endTime / 1000)

    const response = await api.service.txMeeting.getUsableMeetingRooms({
      start_time: startTimestamp,
      end_time: endTimestamp
    })

    if (response.data && response.data.data) {
      response.data.data.forEach((roomData) => {
        const roomIndex = availableRooms.value.findIndex(
          (r) => r.type === roomData.room_type
        )
        if (roomIndex !== -1) {
          availableRooms.value[roomIndex].available =
            roomData.total - roomData.reserved
        }
      })

      // 自动选中最小方数的可用会议室
      const availableRoom = availableRooms.value
        .filter((room) => room.available > 0)
        .sort((a, b) => a.type - b.type)[0]

      if (availableRoom) {
        const index = availableRooms.value.findIndex(
          (room) => room.type === availableRoom.type
        )
        if (index !== -1) {
          selectRoom(index)
        }
      }
    }
  } catch (error) {
    console.error('Error fetching available rooms:', error)
    Notify.create({
      message: tc('获取可用会议室失败'),
      type: 'negative',
      icon: 'error',
      position: 'top'
    })
  } finally {
    loadingAvailableRooms.value = false
    checkFormValid() // 获取完后检查表单状态
  }
}

// 选择周期会议
const selectPeriodicMeeting = (meeting: MeetingInfo, index: number) => {
  try {
    // 更新选中的周期会议索引
    selectedPeriodicMeetingIndex.value = index

    // 获取当前时间戳（秒）
    const now = Math.floor(Date.now() / 1000)

    // 计算开始时间和结束时间
    let startTimestamp = meeting.start_time
    const endTimestamp = meeting.end_time

    // 如果会议已经开始，则将开始时间调整为当前时间后的最近15分钟整点
    if (now > startTimestamp) {
      // 将当前时间转换为Date对象
      const currentDate = new Date()
      // 向上取整到最近的15分钟
      const roundedDate = roundTimeToQuarter(currentDate, true)
      // 转换回时间戳（秒）
      startTimestamp = Math.floor(roundedDate.getTime() / 1000)
    }

    // 更新时间选择器模型
    const startDate = new Date(startTimestamp * 1000)
    const endDate = new Date(endTimestamp * 1000)

    // 更新时间选择器模型
    reserveTimeModel.value.startDate = dayjs(startDate).format('YYYY-MM-DD')
    reserveTimeModel.value.startTime = dayjs(startDate).format('HH:mm')
    reserveTimeModel.value.endDate = dayjs(endDate).format('YYYY-MM-DD')
    reserveTimeModel.value.endTime = dayjs(endDate).format('HH:mm')

    // 更新主表单
    meetingForm.value.startTime = formatDateTimeModel(
      reserveTimeModel.value.startDate,
      reserveTimeModel.value.startTime
    )
    meetingForm.value.endTime = formatDateTimeModel(
      reserveTimeModel.value.endDate,
      reserveTimeModel.value.endTime
    )

    // 清除房间选择
    availableRooms.value.forEach((room) => {
      room.selected = false
    })

    // 会自动触发fetchAvailableRooms因为我们已经更新了时间
  } catch (error) {
    console.error('选择周期会议时间段失败', error)
    Notify.create({
      message: tc('选择周期会议时间段失败'),
      type: 'negative',
      position: 'top'
    })
  }
}

// 会议室可用性概览相关数据
interface MeetingRoomUsableIntervalsResponse {
  start_time: number;
  end_time: number;
  data: {
    room_type: number;
    intervals: {
      start: number;
      end: number;
      reservable: number;
      total: number;
    }[];
  }[];
}

// 会议室类型定义
const MEETING_ROOM_DEFINITIONS = [
  { type: 50, name: '50方会议室' },
  { type: 100, name: '100方会议室' },
  { type: 300, name: '300方会议室' },
  { type: 500, name: '500方会议室' },
  { type: 1000, name: '1000方会议室' }
]

// 会议室可用性概览数据
const rawAvailabilityData = ref<MeetingRoomUsableIntervalsResponse[]>([])
const loadingAvailability = ref(false)
const availabilityExpanded = useLocalStorage('meeting-availability-expanded', true)
const calendarViewDate = ref(new Date())
// 添加数据就绪标志
const dataReady = computed(() => !loadingAvailability.value && rawAvailabilityData.value.length > 0)

// 添加日历滚动容器的引用
const calendarBodyRef = ref<HTMLElement | null>(null)

// 自动滚动到7:30位置的函数
const scrollToWorkingHours = () => {
  if (!calendarBodyRef.value) return

  // 计算7:30对应的位置
  // 每个时间槽高度20px，7:30是第15个时间槽（7*2 + 1 = 15）
  const targetSlotIndex = 7 * 2 + 1 // 7:30对应的索引
  const slotHeight = 20 // 每个时间槽的高度（px）
  const scrollPosition = targetSlotIndex * slotHeight

  // 平滑滚动到目标位置
  calendarBodyRef.value.scrollTo({
    top: scrollPosition,
    behavior: 'smooth'
  })
}

// 监听数据就绪状态，自动滚动到工作时间
watch(dataReady, (isReady) => {
  if (isReady) {
    // 使用nextTick确保DOM已更新
    nextTick(() => {
      scrollToWorkingHours()
    })
  }
})

// 监听expansion item展开状态，展开时滚动到工作时间
watch(availabilityExpanded, (isExpanded) => {
  if (isExpanded && dataReady.value) {
    // 使用nextTick确保DOM已更新
    nextTick(() => {
      // 添加一个小延迟，确保expansion动画完成
      setTimeout(() => {
        scrollToWorkingHours()
      }, 350) // Quasar expansion动画通常是300ms，添加50ms缓冲
    })
  }
})

// 时间槽类型定义
interface SlotAvailabilityInfo {
  timeLabel: string;
  startTimestamp: number;
  endTimestamp: number;
  isGenerallyAvailable: boolean;
  isPast: boolean; // 添加标记过去时间的字段
  tooltipDetails: {
    type: RoomType;
    typeName: string;
    reservable: number;
    total: number;
  }[];
}

// 日历天信息类型定义
interface DayAvailabilityInfo {
  date: Date;
  dateLabel: string;
  dayOfWeekLabel: string;
  slots: SlotAvailabilityInfo[];
}

// 获取一天的开始和结束时间戳
const getDayBoundaries = (date: Date): { startTimestamp: number, endTimestamp: number } => {
  const dayStart = new Date(date)
  dayStart.setHours(0, 0, 0, 0)

  const dayEnd = new Date(date)
  // 设置为下一天的00:00:00作为当天的结束
  dayEnd.setDate(dayEnd.getDate() + 1)
  dayEnd.setHours(0, 0, 0, 0)

  return {
    startTimestamp: Math.floor(dayStart.getTime() / 1000),
    endTimestamp: Math.floor(dayEnd.getTime() / 1000)
  }
}

// 新的半小时对齐函数
const getNextHalfHourTime = (): number => {
  const now = new Date()
  const minutes = now.getMinutes()

  // 当前分钟所处的半小时段 (0-29, 30-59)
  const isFirstHalf = minutes < 30

  // 设置为下一个半小时的开始
  if (isFirstHalf) {
    // 当前处于小时的前半段，下一个半小时就是当前小时的30分
    now.setMinutes(30, 0, 0)
  } else {
    // 当前处于小时的后半段，下一个半小时就是下一个小时的0分
    now.setHours(now.getHours() + 1, 0, 0, 0)
  }

  // 添加额外缓冲（可选，如1分钟）
  now.setSeconds(now.getSeconds() + 60)

  return Math.floor(now.getTime() / 1000)
}

// 修改fetchDayAvailabilityData函数，使用新的时间对齐函数
const fetchDayAvailabilityData = async (date: Date): Promise<MeetingRoomUsableIntervalsResponse | null> => {
  try {
    // 获取日期的边界时间戳
    const { startTimestamp, endTimestamp } = getDayBoundaries(date)

    // 对于当天，从下一个半小时开始查询
    const isToday = dayjs(date).isSame(dayjs(), 'day')
    const effectiveStartTime = isToday ? getNextHalfHourTime() : startTimestamp

    // 使用原始的结束时间，不再限制为24小时
    const effectiveEndTime = endTimestamp

    // 如果开始时间已经超过结束时间，返回null
    if (effectiveStartTime >= effectiveEndTime) {
      return null
    }

    console.log(`请求时间范围: ${dayjs(effectiveStartTime * 1000).format('YYYY/MM/DD HH:mm:ss')} - ${dayjs(effectiveEndTime * 1000).format('YYYY/MM/DD HH:mm:ss')}`)

    // 调用API获取数据
    const response = await api.service.txMeeting.getUsableMeetingRoomIntervals({
      start_time: effectiveStartTime,
      end_time: effectiveEndTime
    })

    return response.data
  } catch (error) {
    console.error(`获取${dayjs(date).format('YYYY-MM-DD')}的会议室可用性数据失败:`, error)
    return null
  }
}

// 获取会议室可用性数据
const fetchRoomAvailabilityData = async () => {
  loadingAvailability.value = true
  rawAvailabilityData.value = []

  try {
    const startDate = new Date(calendarViewDate.value)
    startDate.setHours(0, 0, 0, 0)

    // 并行请求7天的数据
    const promises = []
    for (let i = 0; i < 7; i++) {
      const currentDate = new Date(startDate)
      currentDate.setDate(startDate.getDate() + i)
      promises.push(fetchDayAvailabilityData(currentDate))
    }

    // 等待所有请求完成
    const results = await Promise.all(promises)

    // 过滤掉null结果并保存数据
    rawAvailabilityData.value = results.filter(result => result !== null) as MeetingRoomUsableIntervalsResponse[]
  } catch (error) {
    console.error('获取会议室可用性数据失败:', error)
    Notify.create({
      message: tc('获取会议室可用性数据失败'),
      type: 'negative',
      icon: 'error',
      position: 'top'
    })
  } finally {
    loadingAvailability.value = false
  }
}

// 日历视图数据
const calendarDaysAndSlots = computed<DayAvailabilityInfo[]>(() => {
  const result: DayAvailabilityInfo[] = []
  const startDate = new Date(calendarViewDate.value)
  startDate.setHours(0, 0, 0, 0)

  // 当前时间
  const now = new Date()

  // 计算当前所处半小时的结束时间戳
  const currentHalfHourEnd = new Date(now)
  if (now.getMinutes() < 30) {
    // 在小时的前半段，半小时结束时间是当前小时的30分
    currentHalfHourEnd.setMinutes(30, 0, 0)
  } else {
    // 在小时的后半段，半小时结束时间是下一个小时的0分
    currentHalfHourEnd.setHours(now.getHours() + 1, 0, 0, 0)
  }
  const currentHalfHourEndTimestamp = Math.floor(currentHalfHourEnd.getTime() / 1000)

  // 生成7天的日历数据
  for (let dayOffset = 0; dayOffset < 7; dayOffset++) {
    const currentDate = new Date(startDate)
    currentDate.setDate(startDate.getDate() + dayOffset)

    const dayInfo: DayAvailabilityInfo = {
      date: new Date(currentDate),
      dateLabel: dayjs(currentDate).format('MM/DD'),
      dayOfWeekLabel: getDayOfWeekText(currentDate),
      slots: []
    }

    // 获取当天的数据
    const dayData = rawAvailabilityData.value.find(data => {
      const dataDate = new Date(data.start_time * 1000)
      return dayjs(dataDate).isSame(dayjs(currentDate), 'day')
    })

    // 生成当天的48个时间槽
    for (let hour = 0; hour < 24; hour++) {
      for (let minute = 0; minute < 60; minute += 30) {
        const slotStart = new Date(currentDate)
        slotStart.setHours(hour, minute, 0, 0)

        const slotEnd = new Date(slotStart)
        slotEnd.setMinutes(slotEnd.getMinutes() + 30)

        const startTimestamp = Math.floor(slotStart.getTime() / 1000)
        const endTimestamp = Math.floor(slotEnd.getTime() / 1000)

        // 判断时间段是否已过（结束时间小于等于当前半小时的结束时间）
        const isPastTime = endTimestamp <= currentHalfHourEndTimestamp

        // 创建时间槽信息
        const slotInfo: SlotAvailabilityInfo = {
          timeLabel: `${getTimeSlotLabel(hour, minute)} - ${getTimeSlotLabel(
            minute + 30 >= 60 ? (hour + 1) % 24 : hour,
            minute + 30 >= 60 ? 0 : minute + 30
          )}`,
          startTimestamp,
          endTimestamp,
          isGenerallyAvailable: false,
          isPast: isPastTime,
          tooltipDetails: []
        }

        // 如果是过去的时间段，不需要判断可用性，直接填充默认值（全部不可用）
        if (isPastTime) {
          // 对于过去的时间段，不显示任何会议室信息
          slotInfo.tooltipDetails = []
        } else if (dayData) {
          // 检查该时间槽是否有可用数据，默认为不可用
          let anyRoomAvailable = false

          // 只遍历API响应中实际存在的会议室类型
          dayData.data.forEach(roomTypeData => {
            // 从预定义列表中找到对应的会议室名称
            const roomDef = MEETING_ROOM_DEFINITIONS.find(def => def.type === roomTypeData.room_type)

            if (roomDef) {
              // 查找覆盖当前时间段的区间
              // 修改匹配逻辑，只要开始时间能匹配上即可
              const matchingInterval = roomTypeData.intervals.find(interval => {
                // 向下取整到半小时，确保能匹配上16:00-16:30这样的时间段
                const intervalStartAligned = Math.floor(interval.start / 1800) * 1800
                const intervalEndAligned = Math.ceil(interval.end / 1800) * 1800
                return intervalStartAligned <= startTimestamp && intervalEndAligned > startTimestamp
              })

              if (matchingInterval) {
                // 如果有可用会议室，标记为可用
                if (matchingInterval.reservable > 0) {
                  anyRoomAvailable = true
                }

                // 添加详细信息用于tooltip
                slotInfo.tooltipDetails.push({
                  type: roomDef.type as RoomType,
                  typeName: roomDef.name,
                  reservable: matchingInterval.reservable,
                  total: matchingInterval.total
                })
              } else {
                // 如果没有匹配的区间，添加默认值（全部不可用）
                slotInfo.tooltipDetails.push({
                  type: roomDef.type as RoomType,
                  typeName: roomDef.name,
                  reservable: 0,
                  total: 0
                })
              }
            }
          })

          // 更新可用性状态
          slotInfo.isGenerallyAvailable = anyRoomAvailable
        } else {
          // 没有数据，不显示任何会议室信息
          slotInfo.tooltipDetails = []
        }

        dayInfo.slots.push(slotInfo)
      }
    }

    result.push(dayInfo)
  }

  return result
})

// 刷新会议室可用性数据
const refreshAvailability = (event?: Event) => {
  if (event) {
    event.stopPropagation() // 阻止事件冒泡，避免触发折叠/展开
  }
  fetchRoomAvailabilityData()
}

// 添加回获取星期几的文本函数
const getDayOfWeekText = (date: Date): string => {
  const days = ['周日', '周一', '周二', '周三', '周四', '周五', '周六']
  return days[date.getDay()]
}

// 添加回获取时间槽标签函数
const getTimeSlotLabel = (hour: number, minute: number): string => {
  return `${hour.toString().padStart(2, '0')}:${minute.toString().padStart(2, '0')}`
}

// 添加回生成所有时间槽标签函数
const getTimeSlotLabels = (): string[] => {
  const labels = []
  for (let hour = 0; hour <= 24; hour++) {
    labels.push(getTimeSlotLabel(hour, 0))
    labels.push(getTimeSlotLabel(hour, 30))
  }
  return labels
}
</script>

<template>
  <q-scroll-area style="height: calc(100vh - 50px)">
    <div class="q-pa-md">
      <div class="text-h6">
        {{ tc("预定会议") }}（北京时间）
      </div>

      <!-- 会议预定须知 -->
      <q-expansion-item class="q-mb-sm" icon="info" dense v-model="termsExpanded" :label="tc('会议预定须知')"
        header-class="text-primary bg-grey-2" expand-separator v-if="termsConditions || loadingTerms">
        <div class="q-px-lg q-pb-sm bg-grey-2">
          <q-skeleton type="text" v-if="loadingTerms" />
          <div v-else v-html="termsConditions"></div>
        </div>
      </q-expansion-item>

      <!-- 可用会议室概览 -->
      <q-expansion-item class="q-mb-sm" dense v-model="availabilityExpanded" expand-separator
        header-class="text-primary bg-grey-2">
        <template v-slot:header>
          <q-item-section avatar>
            <q-icon name="event_available" />
          </q-item-section>
          <q-item-section>
            {{ tc("可用会议室概览") }}
          </q-item-section>
          <q-item-section side>
            <q-btn flat round dense icon="refresh" @click.stop="refreshAvailability" :loading="loadingAvailability">
              <q-tooltip>{{ tc('刷新') }}</q-tooltip>
            </q-btn>
          </q-item-section>
        </template>

        <div class="bg-grey-2 position-relative">
          <q-inner-loading :showing="loadingAvailability">
            <q-spinner-dots size="40px" color="primary" />
          </q-inner-loading>

          <div v-if="calendarDaysAndSlots.length > 0" class="availability-calendar-container">
            <!-- 日历头部 (日期行) -->
            <div class="calendar-header row no-wrap">
              <div class="time-column-header"></div>
              <div v-for="(dayInfo, dayIndex) in calendarDaysAndSlots" :key="dayIndex" class="day-column-header">
                <div class="date-label">{{ dayInfo.dateLabel }}</div>
                <div class="day-label">{{ dayInfo.dayOfWeekLabel }}</div>
              </div>
            </div>

            <!-- 日历主体 (时间槽) -->
            <div class="calendar-body row no-wrap" ref="calendarBodyRef">
              <!-- 时间列 (左侧) -->
              <div class="time-column">
                <div v-for="(label, index) in getTimeSlotLabels()" :key="index" class="time-slot-label"
                  v-show="index % 2 === 0">
                  {{ label === '00:00' ? '' : label }}
                </div>
              </div>

              <!-- 数据列 (每天的时间槽) -->
              <div v-for="(dayInfo, dayIndex) in calendarDaysAndSlots" :key="dayIndex" class="day-column">
                <div v-for="(slotInfo, slotIndex) in dayInfo.slots" :key="slotIndex" class="time-slot" :class="{
                  'bg-green-2': dataReady && !slotInfo.isPast && slotInfo.isGenerallyAvailable,
                  'bg-red-2': dataReady && !slotInfo.isPast && !slotInfo.isGenerallyAvailable,
                  'bg-grey-4': slotInfo.isPast,
                  'bg-grey-2': !dataReady && !slotInfo.isPast,
                  'hour-boundary': slotIndex % 2 !== 0
                }">
                  <q-tooltip class="text-subtitle1" style="background-color: rgba(0, 0, 0, 0.3);" :offset="[0, 0]">
                    <div class="">
                      {{ dayInfo.dateLabel }} {{ dayInfo.dayOfWeekLabel }} {{ slotInfo.timeLabel }}
                    </div>
                    <div v-if="slotInfo.isPast" class="">
                      {{ tc('已过时间段') }}
                    </div>
                    <div v-else-if="!dataReady" class="">
                      {{ tc('数据加载中...') }}
                    </div>
                    <div v-else-if="slotInfo.tooltipDetails.length === 0" class="">
                      {{ tc('暂无会议室信息') }}
                    </div>
                    <div v-else v-for="detail in slotInfo.tooltipDetails" :key="detail.type" class="">
                      {{ detail.typeName }}: {{ tc('剩余') }} {{ detail.reservable }}
                    </div>
                  </q-tooltip>
                </div>
              </div>
            </div>
          </div>

          <div v-else-if="!loadingAvailability" class="text-center q-pa-md">
            {{ tc("暂无可用会议室数据") }}
          </div>
        </div>
      </q-expansion-item>

      <!-- 步骤1：输入会议信息 -->
      <q-card class="q-mb-md">

        <div class="q-px-md q-py-sm text-weight-bold">{{ tc("步骤1：查询会议详情") }}</div>

        <div class="q-px-md q-pb-sm row items-center q-gutter-sm">
          <!-- 腾讯会议号 -->
          <q-input class="col-auto" v-model="meetingForm.meetingId" :label="tc('腾讯会议号')" outlined dense clearable
            @update:model-value="checkFormValid" />

          <q-btn class="col-auto" color="primary" :label="tc('查询')" @click="fetchMeetingInfo"
            :disable="!meetingForm.meetingId || loadingMeetingInfo" :loading="loadingMeetingInfo" />

        </div>
        <!-- 会议信息展示区域 -->
        <div v-if="meetingInfo" class="q-mx-md q-pb-md">
          <div class="row q-col-gutter-sm">
            <!-- 会议详情 -->
            <div class="col-12 col-sm-12 col-md-4">
              <div class="meeting-info-section info-card">
                <div class="section-header row items-center">
                  {{ tc("会议信息") }}
                  <q-badge outline class="q-ml-sm text-grey-8">ID: {{ meetingInfo.meeting_id }}</q-badge>
                </div>

                <div class="row">
                  <div class="col-12">
                    <q-item dense class="rounded-borders bg-grey-1">
                      <q-item-section>
                        <q-item-label caption>{{
                          tc("会议号")
                          }}</q-item-label>
                        <q-item-label class="text-weight-medium">{{
                          meetingInfo.meeting_code
                          }}</q-item-label>
                      </q-item-section>
                    </q-item>
                  </div>

                  <div class="col-12">
                    <q-item dense class="rounded-borders bg-grey-1">
                      <q-item-section>
                        <q-item-label caption>{{
                          tc("会议主题")
                          }}</q-item-label>
                        <q-item-label class="text-weight-medium">{{
                          meetingInfo.subject
                          }}</q-item-label>
                      </q-item-section>
                    </q-item>
                  </div>

                  <div class="col-12">
                    <q-item dense class="rounded-borders bg-grey-1">
                      <q-item-section>
                        <q-item-label caption>{{
                          tc("创建人")
                          }}</q-item-label>
                        <q-item-label class="text-weight-medium">{{ meetingInfo.nick_name }} ({{
                          meetingInfo.userid
                          }})</q-item-label>
                      </q-item-section>
                    </q-item>
                  </div>

                  <div class="col-12">
                    <q-item dense class="rounded-borders bg-grey-1">
                      <q-item-section>
                        <q-item-label caption>{{
                          tc("会议类型")
                          }}</q-item-label>
                        <q-item-label>
                          <q-chip size="md" text-color="white" :color="meetingInfo.meeting_type === 1
                            ? 'secondary'
                            : 'info'
                            " class="q-pa-sm">
                            {{
                              formatMeetingType(
                                meetingInfo.meeting_type
                              )
                            }}
                          </q-chip>
                        </q-item-label>
                      </q-item-section>
                    </q-item>
                  </div>

                  <div class="col-12">
                    <q-item dense class="rounded-borders bg-grey-1">
                      <q-item-section>
                        <q-item-label caption>{{
                          tc("会议状态")
                          }}</q-item-label>
                        <q-item-label>
                          <q-chip text-color="white" :color="getStateColor(
                            meetingInfo.start_time,
                            meetingInfo.end_time
                          )
                            " class="q-pa-sm">
                            {{
                              formatMeetingState(
                                meetingInfo.start_time,
                                meetingInfo.end_time
                              )
                            }}
                          </q-chip>
                        </q-item-label>
                      </q-item-section>
                    </q-item>
                  </div>
                </div>
              </div>
            </div>

            <!-- 时间信息 -->
            <div class="col-12 col-sm-12 col-md-4">
              <div class="meeting-info-section info-card">
                <div class="section-header">
                  {{ tc("时间信息") }}
                </div>
                <div class="row">
                  <div class="col-12">
                    <q-item dense class="rounded-borders bg-grey-1">
                      <q-item-section>
                        <q-item-label caption>{{
                          tc("开始时间")
                          }}</q-item-label>
                        <q-item-label class="text-weight-medium">{{
                          formatDateTime(meetingInfo.start_time)
                          }}</q-item-label>
                      </q-item-section>
                    </q-item>
                  </div>

                  <div class="col-12">
                    <q-item dense class="rounded-borders bg-grey-1">
                      <q-item-section>
                        <q-item-label caption>{{
                          tc("结束时间")
                          }}</q-item-label>
                        <q-item-label class="text-weight-medium">{{
                          formatDateTime(meetingInfo.end_time)
                          }}</q-item-label>
                      </q-item-section>
                    </q-item>
                  </div>

                  <div class="col-12">
                    <q-item dense class="rounded-borders bg-grey-1">
                      <q-item-section>
                        <q-item-label caption>{{
                          tc("时长")
                          }}</q-item-label>
                        <q-item-label class="text-weight-medium">{{
                          (
                            (meetingInfo.end_time -
                              meetingInfo.start_time) /
                            60
                          ).toFixed(0)
                        }}
                          {{ tc("分钟") }}</q-item-label>
                      </q-item-section>
                    </q-item>
                  </div>
                </div>
              </div>
            </div>

            <!-- 周期会议时间段 -->
            <div v-if="
              meetingInfo.meeting_type === 1 &&
              periodicMeetings.length > 0
            " class="col-12 col-sm-12 col-md-4">
              <div class="meeting-info-section info-card">
                <div class="section-header">
                  {{ tc("周期会议时间段") }}
                </div>
                <div class="row">
                  <div v-for="(meeting, index) in periodicMeetings" :key="index" class="col-12">
                    <q-item dense class="rounded-borders bg-grey-1" :class="{
                      'cursor-pointer': true,
                      'selected-meeting': selectedPeriodicMeetingIndex === index
                    }" @click="selectPeriodicMeeting(meeting, index)" clickable>
                      <div class="row items-center full-width justify-between meeting-option-row">
                        <!-- 状态标签 -->
                        <div class="meeting-chip-container">
                          <q-chip size="sm" text-color="white" :color="getStateColor(
                            meeting.start_time,
                            meeting.end_time
                          )" class="meeting-status-chip">
                            {{
                              formatMeetingState(
                                meeting.start_time,
                                meeting.end_time
                              )
                            }}
                          </q-chip>
                        </div>

                        <!-- 时间段信息 -->
                        <div class="meeting-time-container">
                          <span class="meeting-time-text text-weight-medium"
                            :class="{ 'text-grey': meeting.meeting_state === 3 }">
                            {{ formatDateTime(meeting.start_time) }}
                            <q-icon name="arrow_forward" class="q-px-xs" />
                            {{ formatDateTime(meeting.end_time) }}
                          </span>
                        </div>

                        <!-- 选择状态图标 -->
                        <div class="meeting-select-icon">
                          <q-icon
                            :name="selectedPeriodicMeetingIndex === index ? 'check_circle' : 'radio_button_unchecked'"
                            :color="selectedPeriodicMeetingIndex === index ? 'primary' : 'grey-5'" size="sm" />
                        </div>
                      </div>
                    </q-item>
                  </div>
                </div>
              </div>
            </div>
          </div>
        </div>
      </q-card>

      <!-- 步骤2：选择可用会议室 -->
      <q-card class="q-mb-md">

        <div class="row items-center q-px-md q-py-sm text-weight-bold">{{ tc("步骤2：根据时间选择可用会议室") }}</div>

        <div v-if="meetingInfo">
          <!-- 拆分为三行显示：参会人数、预定时间、可用会议室 -->
          <div>

            <!-- 时间选择器区域 -->
            <div class="q-px-md">
              <div class="row items-center text-weight-bold">
                {{ tc("请选择预定时间") }}

                <!-- 会议时长 -->
                <span v-if="timeValid" class="col-12 col-sm-auto col-md-auto time-caption q-ml-sm">
                  {{ tc('会议时长') }}
                  {{ currentDuration.hours }}{{ tc("小时") }}
                  {{ currentDuration.minutes }}{{ tc("分钟") }}
                </span>

              </div>
              <div class="row items-center q-col-gutter-md">
                <!-- 开始时间 -->
                <div class="col-12 col-sm-auto col-md-auto">
                  <div class="time-input-group">
                    <div class="row items-center no-wrap">

                      <div>
                        {{ tc("开始时间") }}
                      </div>
                      <div class="q-py-sm q-px-sm">
                        {{ reserveTimeModel.startDate }}
                      </div>
                      <q-select v-model="reserveTimeModel.startTime" :options="timeOptions" option-label="label"
                        emit-value map-options dense outlined class="time-input input-common" />
                    </div>
                  </div>
                </div>

                <!-- 结束时间 -->
                <div class="col-12 col-sm-auto col-md-auto">
                  <div class="time-input-group">
                    <div class="row items-center no-wrap">

                      <div>
                        {{ tc("结束时间") }}
                      </div>
                      <div class="q-py-sm q-px-sm">
                        {{ reserveTimeModel.endDate }}
                      </div>
                      <q-select v-model="reserveTimeModel.endTime" :options="timeOptions" option-label="label"
                        emit-value map-options dense outlined class="time-input input-common" />
                    </div>
                  </div>
                </div>

                <div class="col-12 col-sm-auto col-md-auto row items-center">

                  <q-btn v-if="meetingInfo" class="col-auto" dense :label="tc('重置时间')" color="primary" flat padding="0"
                    icon="refresh" @click="resetToMeetingTime" />
                </div>
              </div>

              <!-- 错误提示区域 -->
              <div v-if="meetingForm.startTime && meetingForm.endTime && !timeValid"
                class="q-pb-sm row justify-start items-center">
                <q-banner dense rounded class="col-auto bg-negative text-white">
                  <template v-slot:avatar>
                    <q-icon name="warning" />
                  </template>
                  <div v-if="timeErrors.invalidDateTimeFormat">{{ tc("日期或时间格式不正确或不完整") }}</div>
                  <div v-if="timeErrors.startTimeInPast">{{ tc("开始时间必须晚于当前时间") }}</div>
                  <div v-if="timeErrors.endTimeBeforeStart">{{ tc("结束时间必须晚于开始时间") }}</div>
                  <div v-if="timeErrors.durationTooShort">{{ tc("会议时长必须至少15分钟") }}</div>
                  <div v-if="timeErrors.durationTooLong">{{ tc("会议时长不能超过24小时") }}</div>
                </q-banner>
              </div>
            </div>
          </div>

          <!-- 可用会议室区域 -->
          <div v-if="
            timeValid &&
            (availableRooms.some((room) => room.available > 0) ||
              loadingAvailableRooms)
          " class="q-px-md q-py-md">
            <div class="text-weight-bold">{{ tc("请选择可用会议室") }}
              <span class="time-caption q-ml-sm">
                {{
                  meetingForm.startTime
                    ? new Date(meetingForm.startTime).toLocaleString()
                    : ""
                }}
                -
                {{
                  meetingForm.endTime
                    ? new Date(meetingForm.endTime).toLocaleString()
                    : ""
                }}
              </span>
            </div>

            <div v-if="loadingAvailableRooms" class="row justify-center q-py-md">
              <q-spinner size="md" color="primary" />
              <div class="q-ml-sm">{{ tc("正在查询可用会议室...") }}</div>
            </div>

            <div v-else class="">
              <div class="row">
                <div v-for="(room, index) in availableRooms" :key="room.type" class="col-12 col-sm-4 col-md-2 q-pr-md">
                  <q-card :class="[
                    'room-card',
                    room.selected ? 'room-card-selected' : '',
                    room.available === 0 ? 'room-card-disabled' : 'cursor-pointer',
                  ]" @click="room.available > 0 && selectRoom(index)">
                    <q-card-section class="q-py-sm room-card-content">
                      <div class="row items-center no-wrap">
                        <div class="row full-width justify-between items-center">
                          <div class="room-name">{{ tc(room.name) }}</div>

                          <div class="row items-center">
                            <div>
                              {{ tc("剩余") }}
                            </div>
                            <span :class="[
                              room.available === 0
                                ? 'text-negative'
                                : 'text-positive',
                              'available-count',
                            ]" class="text-body1">{{ room.available }}</span>
                          </div>
                        </div>
                      </div>
                    </q-card-section>
                  </q-card>
                </div>
              </div>
            </div>
          </div>
        </div>

        <div v-else class="row justify-center q-pa-sm text-grey-7">
          <div>{{ tc("请查询会议信息") }}</div>
        </div>

      </q-card>

      <!-- 步骤3：确认预定 -->
      <q-card class="q-mb-md">

        <div class="q-px-md q-py-sm text-weight-bold">{{ tc("步骤3：确认预定") }}</div>

        <div v-if="formValid">
          <div class="q-mx-md">

            <div class="row">
              <div class="col-12 col-md-6">
                <div class="booking-info-section">
                  <div class="row">
                    <!-- 会议信息 -->
                    <div class="col-12">
                      <q-item dense class="rounded-borders bg-grey-1">
                        <q-item-section>
                          <q-item-label caption>{{ tc("会议号") }}</q-item-label>
                          <q-item-label class="text-weight-medium">
                            {{ meetingInfo ? meetingInfo.meeting_code : meetingForm.meetingId }}
                          </q-item-label>
                        </q-item-section>
                      </q-item>
                    </div>

                    <div class="col-12">
                      <q-item dense class="rounded-borders bg-grey-1">
                        <q-item-section>
                          <q-item-label caption>{{ tc("会议主题") }}</q-item-label>
                          <q-item-label class="text-weight-medium">
                            {{ meetingForm.topic }}
                          </q-item-label>
                        </q-item-section>
                      </q-item>
                    </div>

                    <!-- 会议室信息 -->
                    <div class="col-12">
                      <q-item dense class="rounded-borders bg-grey-1">
                        <q-item-section>
                          <q-item-label caption>{{ tc("会议室规格") }}</q-item-label>
                          <q-item-label class="text-weight-medium">
                            {{availableRooms.find(room => room.selected)?.name || ''}}
                          </q-item-label>
                        </q-item-section>
                      </q-item>
                    </div>
                  </div>
                </div>
              </div>

              <div class="col-12 col-md-6">
                <div class="booking-info-section">
                  <div class="row">
                    <!-- 时间信息 -->
                    <div class="col-12">
                      <q-item dense class="rounded-borders bg-grey-1">
                        <q-item-section>
                          <q-item-label caption>{{ tc("开始时间") }}</q-item-label>
                          <q-item-label class="text-weight-medium">
                            {{ new Date(meetingForm.startTime).toLocaleString() }}
                          </q-item-label>
                        </q-item-section>
                      </q-item>
                    </div>

                    <div class="col-12">
                      <q-item dense class="rounded-borders bg-grey-1">
                        <q-item-section>
                          <q-item-label caption>{{ tc("结束时间") }}</q-item-label>
                          <q-item-label class="text-weight-medium">
                            {{ new Date(meetingForm.endTime).toLocaleString() }}
                          </q-item-label>
                        </q-item-section>
                      </q-item>
                    </div>

                    <div class="col-12">
                      <q-item dense class="rounded-borders bg-grey-1">
                        <q-item-section>
                          <q-item-label caption>{{ tc("会议时长") }}</q-item-label>
                          <q-item-label class="text-weight-medium">
                            {{ currentDuration.hours }}{{ tc("小时") }} {{ currentDuration.minutes }}{{ tc("分钟") }}
                          </q-item-label>
                        </q-item-section>
                      </q-item>
                    </div>
                  </div>
                </div>
              </div>
            </div>
          </div>
        </div>

        <div v-else class="row justify-center q-pa-sm text-grey-7">
          <div>{{ tc("请完成前两个步骤") }}</div>
        </div>

        <div class="row justify-center q-pa-md q-gutter-md">
          <q-btn :label="tc('确认预定')" color="primary" padding="sm xl" @click="confirmBooking"
            :disable="!formValid || submittingBooking" :loading="submittingBooking" />
        </div>

      </q-card>
    </div>
  </q-scroll-area>
</template>

<style lang="scss" scoped>
.room-card {
  transition: all 0.3s ease;
  box-sizing: border-box;
  border: 2px solid transparent;

  &:hover:not(.room-card-disabled) {
    border-color: $primary;
  }

  &.room-card-selected {
    border: 2px solid $primary;
    background-color: rgba(25, 118, 210, 0.3);
  }

  &.room-card-disabled {
    opacity: 0.6;
    cursor: not-allowed;
  }
}

// 周期会议时间段样式
.cursor-pointer {
  cursor: pointer;
}

.past-meeting {
  opacity: 0.65;
  cursor: not-allowed;
}

.line-through {
  text-decoration: line-through;
}

// 周期会议选择项悬停效果
.cursor-pointer:hover {
  background-color: rgba(25, 118, 210, 0.1);
}

// 已选中的周期会议样式
.selected-meeting {
  background-color: rgba(86, 162, 232, 0.15) !important;
}

.disabled-card {
  opacity: 0.6;
  pointer-events: none;
}

/* 弹性布局辅助类 */
.d-flex {
  display: flex;
}

.align-center {
  align-items: center;
}

/* 响应式布局 */
@media (max-width: 599px) {
  .row.q-col-gutter-md {
    margin-left: -8px;
    margin-right: -8px;
  }

  .row.q-col-gutter-md>.col-12 {
    padding-left: 8px;
    padding-right: 8px;
  }

  .time-label-inline {
    margin-bottom: 4px;
  }
}

/* 统一输入框高度 */
.input-common {
  height: 40px;

  :deep(.q-field__control) {
    height: 40px;
  }
}

/* 标签和输入框水平布局 */
.time-input-row {
  display: flex;
  align-items: center;
  margin-bottom: 8px;
}

.time-label-inline {
  width: 40px;
  font-weight: 500;
  color: #666;
  margin-right: 8px;
}

.time-label {
  font-weight: 500;
  margin-bottom: 8px;
  color: #666;
}

.date-time-inputs {
  display: flex;
  gap: 12px;
  flex: 1;
}

.error-message {
  color: #ff5252;
  font-size: 0.85rem;
  display: flex;
  align-items: center;
  margin-top: 8px;
}

.meeting-info-container {
  border: 1px solid rgba(0, 0, 0, 0.12);
  border-radius: 4px;
  padding: 16px;
}

.meeting-info-section {
  height: 100%;
  // margin-bottom: 8px;
  // padding: 8px;
  border-radius: 4px;
  padding: 8px 8px 0 8px !important; // 顶部和两侧保持内边距，底部去掉
  margin-bottom: 0 !important;

  @media (max-width: 767px) {
    margin-top: 8px;
    margin-bottom: 16px;
    padding-bottom: 0;
    border-bottom: 1px solid rgba(0, 0, 0, 0.12);

    &:last-child {
      border-bottom: none;
    }
  }

  // 去掉最后一个条目的底部间距
  .row>.col-12:last-child {
    padding-bottom: 0;
    margin-bottom: 0;

    .q-item {
      margin-bottom: 0;
    }
  }

  // 减小每个条目的上下间距
  .row>.col-12 {
    margin-bottom: 1px;
  }

  // 最后一个条目没有底部外边距
  .row>.col-12:last-child {
    margin-bottom: 0;
  }
}

.booking-info-section {
  height: 100%;
  margin-bottom: 8px;

  @media (max-width: 1023px) {
    &+& {
      margin-top: 8px;
      padding-top: 8px;
      border-top: 1px solid rgba(0, 0, 0, 0.12);
    }
  }

  // 移动端去除区域间距
  @media (max-width: 767px) {
    margin-bottom: 0; // 去除底部间距

    &+& {
      margin-top: 0; // 去除顶部间距
      padding-top: 0; // 去除内边距
      border-top: none; // 去除边框
    }

    .row .col-12 {
      padding-top: 0;
      padding-bottom: 0;
    }

    .q-item {
      min-height: 0;
      padding-top: 4px;
      padding-bottom: 4px;
      margin-bottom: 0; // 去除条目间距
    }

    .q-item-label.caption {
      margin-bottom: 0;
      font-size: 0.75rem;
    }

    .q-item-label:not(.caption) {
      font-size: 0.85rem;
      line-height: 1.2;
    }

    .text-weight-medium {
      font-size: 0.8rem;
      word-break: break-word;
    }
  }
}

/* 让时间信息在移动设备上更紧凑 */
@media (max-width: 1023px) {
  .row.q-col-gutter-sm {
    margin-top: -4px;
  }

  .col-12 {
    padding-top: 4px;
    padding-bottom: 4px;
  }

  .q-card-section {
    padding: 12px;
  }

  .q-item {
    min-height: auto;
    padding: 8px;
  }

  .q-item-label.caption {
    margin-bottom: 2px;
  }
}

/* 修复标题样式，确保在移动端显示正常不与其他组件交叉 */
.section-title {
  display: block;
  margin-bottom: 12px;
  line-height: 1.5;
  font-size: 1.1rem;
  font-weight: 500;

  @media (max-width: 599px) {
    margin-bottom: 8px;
    font-size: 1rem;
    flex-direction: column;
    align-items: flex-start !important;

    .q-chip {
      margin-left: 0 !important;
      margin-top: 8px;
    }
  }
}

.time-caption {
  display: block;
  margin-top: 4px;
  margin-left: 0 !important;
  font-size: 0.875rem;
  font-weight: normal;
  color: #666;

  @media (min-width: 600px) {
    display: inline;
    margin-top: 0;
    margin-left: 8px !important;
  }
}

.available-count {
  font-size: 1.4em;
  font-weight: 700;
}

.room-card-content {
  padding: 10px 12px;
}

.room-name {
  font-size: 0.95rem;
}

.info-card {
  background-color: #fafafa;
  border-radius: 8px;
  overflow: hidden; // 防止子元素溢出
  padding-bottom: 0 !important;
  margin-bottom: 4px !important;
}

.section-header {
  font-weight: 500;
  color: #333;
  // margin-bottom: 12px;
  // padding-bottom: 8px;
  border-bottom: 1px solid rgba(0, 0, 0, 0.1);
  margin-bottom: 4px;
  padding-bottom: 4px;
}

@media (max-width: 767px) {
  .info-card {
    margin-bottom: 16px;
    box-shadow: 0 1px 2px rgba(0, 0, 0, 0.1);
  }

  .meeting-info-section.info-card {
    padding: 12px 12px 0 12px; // 去掉底部内边距
  }

  // 设置更小的列间距
  .meeting-info-section .row.q-col-gutter-sm {
    margin-left: -2px;
    margin-right: -2px;
    margin-bottom: 0; // 去掉底部外边距
  }

  .meeting-info-section .row.q-col-gutter-sm>* {
    padding-left: 2px;
    padding-right: 2px;
  }

  // 缩小条目间距
  .meeting-info-section .row .col-12 {
    padding-top: 2px;
    padding-bottom: 2px;
  }

  .meeting-info-section .q-item {
    min-height: 0;
    padding-top: 4px;
    padding-bottom: 4px;
    margin-bottom: 4px; // 减小项目间距
  }

  // 最后一个条目的q-item没有底部外边距
  .meeting-info-section .row>.col-12:last-child .q-item {
    margin-bottom: 0;
  }

  .meeting-info-section .q-item-label.caption {
    margin-bottom: 0;
    font-size: 0.75rem;
  }

  .meeting-info-section .q-item-label:not(.caption) {
    font-size: 0.85rem;
    line-height: 1.2;
  }

  // 优化周期会议部分
  .meeting-info-section .q-badge {
    font-size: 0.7rem;
    padding: 2px 4px;
  }

  .meeting-info-section .q-badge.q-pa-sm {
    padding: 2px 4px !important;
  }

  .meeting-info-section .q-icon {
    font-size: 12px;
  }

  // 减小日期时间长文本的字体大小
  .meeting-info-section .text-weight-medium {
    font-size: 0.8rem;
    word-break: break-word;
  }
}

/* 修复会议信息区域底部多余的空白 */
.meeting-info-section .q-item.dense {
  padding: 4px 8px;
  min-height: 0;
}

.meeting-info-section .bg-grey-1 {
  margin-bottom: 4px;
}

.meeting-info-section .col-12:last-child .bg-grey-1 {
  margin-bottom: 0;
}

div[v-if="meetingInfo"].q-mx-md.q-pb-md {
  padding-bottom: 8px !important;
  /* 减少底部内边距 */
}

.meeting-info-section .row.q-col-gutter-sm {
  margin-bottom: 0;
  /* 移除底部外边距 */
}

/* 为特定容器添加底部外边距 */
.col-12.col-sm-12.col-md-4 {
  margin-bottom: 16px;
}

@media (min-width: 768px) {
  .col-12.col-sm-12.col-md-4 {
    margin-bottom: 0; // 在桌面端不需要底部外边距
  }
}

/* 调整所有q-item的内边距 */
.meeting-info-section .q-item {
  padding: 2px 8px !important;
  min-height: 0 !important;
  margin-bottom: 2px !important;
}

.meeting-info-section .q-item-section {
  padding: 2px 0 !important;
}

.meeting-info-section .q-item-label {
  line-height: 1.2 !important;
}

@media (max-width: 767px) {

  /* 在移动端更紧凑 */
  .meeting-info-section .q-item {
    padding: 1px 4px !important;
  }
}

/* 日期文本样式 */
.date-text {
  background-color: #f5f5f5;
  border-radius: 4px;
  min-width: 120px;
  margin-right: 8px;
  border: 1px solid rgba(0, 0, 0, 0.12);
}

// 会议时间标签
.meeting-time-label {
  flex: 1;
}

// 周期会议选项样式
.meeting-option-row {
  flex-wrap: nowrap;
  gap: 8px;
}

.meeting-chip-container {
  flex-shrink: 0;
  min-width: 60px;
}

.meeting-status-chip {
  margin: 0;
}

.meeting-time-container {
  flex: 1;
  min-width: 0; // 确保容器可以缩小
  overflow: hidden; // 防止内容溢出
}

.meeting-time-text {
  display: inline-block;
  word-break: break-word; // 允许在任何字符处换行
  white-space: normal; // 允许换行
  font-size: 0.9rem;
  line-height: 1.2;
}

.meeting-select-icon {
  flex-shrink: 0;
  width: 24px;
  display: flex;
  justify-content: flex-end;
}

@media (max-width: 599px) {
  .meeting-option-row {
    gap: 4px;
  }

  .meeting-time-text {
    font-size: 0.85rem;
  }

  .meeting-status-chip {
    font-size: 0.8rem !important;
    padding: 0 4px !important;
  }
}

/* 可用会议室概览日历样式 */
.position-relative {
  position: relative;
}

.availability-calendar-container {
  width: 100%;
  overflow-x: auto;
  margin-bottom: 16px;
}

.calendar-header {
  display: flex;
  align-items: center;
  border-bottom: 1px solid rgba(0, 0, 0, 0.12);
}

.time-column-header {
  min-width: 20px;
  flex: 0 0 40px;
}

.day-column-header {
  flex: 1;
  min-width: 100px;
  text-align: center;
  border-left: 1px solid rgba(0, 0, 0, 0.12);
}

.date-label {
  font-weight: 500;
  font-size: 0.9rem;
}

.day-label {
  font-size: 0.8rem;
  color: #666;
}

.calendar-body {
  display: flex;
  height: 350px;
  /* 高度固定，内部滚动 */
  overflow-y: auto;
}

.time-column {
  flex: 0 0 40px;
  min-width: 20px;
  display: flex;
  flex-direction: column;
  padding-right: 4px;
}

.time-slot-label {
  flex: 0 0 40px;
  /* 每个时间槽高度40px，显示整点 */
  display: flex;
  align-items: center;
  justify-content: flex-end;
  font-size: 0.75rem;
  color: #666;
  margin-top: -20px;
  margin-bottom: 20px;
}

.day-column {
  flex: 1;
  min-width: 100px;
  display: flex;
  flex-direction: column;
  // border-left: 1px solid rgba(0, 0, 0, 0.12);
}

.time-slot {
  flex: 0 0 20px;
  /* 每个时间槽高度20px，总共48个槽 */
  border-bottom: 1px solid rgba(0, 0, 0, 0.05);
  border-left: 1px solid rgba(0, 0, 0, 0.12);
  transition: all 0.2s ease;
}

.time-slot:hover {
  background-color: rgba(33, 150, 243, 0.55) !important;
}

.hour-boundary {
  border-bottom: 1px solid rgba(0, 0, 0, 0.12);
}

/* 响应式调整 */
@media (max-width: 599px) {

  .time-column-header,
  .time-column {
    min-width: 40px;
    flex: 0 0 40px;
  }

  .day-column-header,
  .day-column {
    min-width: 20px;
  }

  .time-slot-label {
    font-size: 0.7rem;
  }

  .date-label {
    font-size: 0.8rem;
  }

  .day-label {
    font-size: 0.7rem;
  }
}
</style>
